﻿using Microsoft.Extensions.Options;
using System;
using System.Net.Http;
using System.Security.Authentication;
using System.Threading;
using System.Threading.Tasks;
using Tiens.NotificationHub.Core.Extensions;
using Tiens.NotificationHub.Core.Options;
using Tiens.NotificationHub.RemoteServices;

namespace Tiens.NotificationHub.Core.RemoteServices
{
    public class PassportClient : IPassportClient
    {
        private readonly HttpClient _httpClient;

        public PassportClient(HttpClient httpClient, IOptions<IAMOptions> iamOptions)
        {
            httpClient.BaseAddress = new Uri(iamOptions.Value.Url);
            httpClient.DefaultRequestHeaders.Add("Accept", "application/json");

            _httpClient = httpClient;
        }


        public async Task<string> GetOpenIdAsync(string accessToken, CancellationToken cancellationToken = default)
        {
            var response =
                await _httpClient.GetAsync(
                    $"/IAM/oauth/me?accessToken={accessToken}",
                    cancellationToken);
            if (!response.IsSuccessStatusCode)
            {
                throw new AuthenticationException("根据 accessToken 获取 openId 失败");
            }

            var result = await response.Content.ReadAsAsync<OpenIdResult>();
            if (string.IsNullOrWhiteSpace(result.openid))
            {
                throw new AuthenticationException("根据 accessToken 获取 openId 失败,openId 为空");
            }

            return result.openid;
        }

        public async Task<string> GetUserIdAsync(string clientSecret, string openId, CancellationToken cancellationToken = default)
        {
            var queryString = new StringContent($"oauth_consumer_key={clientSecret}&openId={openId}");
            var response =
                await _httpClient.PostAsync(
                    $"/IAM/oauth/getUserInfo", queryString,
                    cancellationToken);
            if (!response.IsSuccessStatusCode)
            {
                throw new AuthenticationException("根据openId 获取用户Id失败");
            }

            var result = await response.Content.ReadAsAsync<TokenResult>();
            if (result.ret != ReturnState.Success)
            {
                throw new AuthenticationException("根据openId 获取用户Id失败");
            }

            return result.uid;
        }

        class TokenResult
        {
            public int ret { get; set; }
            public string msg { get; set; }
            public string uid { get; set; }
        }

        class OpenIdResult
        {
            public string client_id { get; set; }
            public string openid { get; set; }
        }

        class ReturnState
        {
            public const int Success = 0;
            public const int Error = 1;
        }
    }
}
